package org.linlinjava.litemall.db.service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import org.linlinjava.litemall.db.dao.LitemallGoodsMapper;
import org.linlinjava.litemall.db.dao.LitemallGoodsMapperEx;
import org.linlinjava.litemall.db.domain.GoodsQueryVo;
import org.linlinjava.litemall.db.domain.LitemallGoods;
import org.linlinjava.litemall.db.domain.LitemallGoods.Column;
import org.linlinjava.litemall.db.domain.LitemallGoodsExample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
@Service
public class LitemallGoodsService {
    Column[] columns = new Column[]{Column.id, Column.name, Column.brief, Column.picUrl, Column.isHot, Column.isNew, Column.counterPrice, Column.retailPrice, Column.categoryId};

    Column[] columnOpss = new Column[]{Column.id, Column.name,Column.unit};
    @Resource
    private LitemallGoodsMapper goodsMapper;
    @Resource
    private LitemallGoodsMapperEx goodsMapperEx;


    public LitemallGoods findByName(String name){
        return goodsMapper.selectOne(Wrappers.lambdaQuery(LitemallGoods.class)
                .eq(LitemallGoods::getName,name));
    }

    public List<LitemallGoods> filterGoodsByCategoryl3(LambdaQueryWrapper<LitemallGoods> queryWrapper){
        return goodsMapper.selectList(queryWrapper);
    }

    public Page<LitemallGoods> selectPage(Page page,LambdaQueryWrapper<LitemallGoods> queryWrapper){
        return goodsMapper.selectPage(page,queryWrapper);
    }


    public IPage<LitemallGoods> queryByHot(int offset, int limit) {
        LambdaQueryWrapper<LitemallGoods> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(LitemallGoods::getIsHot,true);
        lambdaQueryWrapper.eq(LitemallGoods::getIsOnSale,true);
        lambdaQueryWrapper.eq(LitemallGoods::getDeleted,false);
        lambdaQueryWrapper.orderByDesc(LitemallGoods::getAddTime);
        return goodsMapper.selectPage(new Page<>(offset, limit),lambdaQueryWrapper);
    }

    public List<LitemallGoods> queryByNew(int offset, int limit) {
        LambdaQueryWrapper<LitemallGoods> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(LitemallGoods::getIsNew,true);
        lambdaQueryWrapper.eq(LitemallGoods::getIsOnSale,true);
        lambdaQueryWrapper.eq(LitemallGoods::getDeleted,false);
        lambdaQueryWrapper.orderByDesc(LitemallGoods::getAddTime);
        return goodsMapper.selectPage(new Page<>(offset, limit),lambdaQueryWrapper).getRecords();
    }

    public List<LitemallGoods> queryByCategory(List<Integer> catList, int offset, int limit) {
        LambdaQueryWrapper<LitemallGoods> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(LitemallGoods::getCategoryId,catList);
        lambdaQueryWrapper.eq(LitemallGoods::getIsOnSale,true);
        lambdaQueryWrapper.eq(LitemallGoods::getDeleted,false);
        lambdaQueryWrapper.orderByDesc(LitemallGoods::getAddTime);
        return goodsMapper.selectPage(new Page<>(offset, limit),lambdaQueryWrapper).getRecords();
    }

    public List<LitemallGoods> queryByCategory(Integer catId, int offset, int limit) {
        LambdaQueryWrapper<LitemallGoods> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(LitemallGoods::getCategoryId,catId);
        lambdaQueryWrapper.eq(LitemallGoods::getIsOnSale,true);
        lambdaQueryWrapper.eq(LitemallGoods::getDeleted,false);
        lambdaQueryWrapper.orderByDesc(LitemallGoods::getAddTime);
        return goodsMapper.selectPage(new Page<>(offset, limit),lambdaQueryWrapper).getRecords();
    }

    public List<LitemallGoods> queryByCategoryAll(Integer catId) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        example.or().andCategoryIdEqualTo(catId).andIsOnSaleEqualTo(true).andDeletedEqualTo(false);
        example.setOrderByClause("sort desc");

        //return goodsMapper.selectByExampleSelective(example, columns);
        return goodsMapper.selectList(Wrappers.lambdaQuery(LitemallGoods.class)
                .eq(LitemallGoods::getCategoryId,catId)
                .eq(LitemallGoods::getIsOnSale,1)
                .eq(LitemallGoods::getDeleted,0)
                .orderByAsc(LitemallGoods::getSort));
    }


    public IPage<LitemallGoods> querySelective(Integer[] ids, Integer page, Integer size, String sort, String order) {

        LambdaQueryWrapper<LitemallGoods> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(ids != null && ids.length > 0,LitemallGoods::getId,Arrays.asList(ids));
        lambdaQueryWrapper.eq(LitemallGoods::getIsOnSale,true);
        lambdaQueryWrapper.eq(LitemallGoods::getDeleted,false);
        lambdaQueryWrapper.orderByDesc(LitemallGoods::getAddTime);
        return goodsMapper.selectPage(new Page<>(page, size),lambdaQueryWrapper);
    }

    public LitemallGoods findById(Integer id) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        example.or().andIdEqualTo(id).andDeletedEqualTo(false);
        return goodsMapper.selectOneByExampleWithBLOBs(example);
    }


    public Integer queryOnSaleByShop(Integer shopId) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        example.or().andShopIdEqualTo(shopId).andIsOnSaleEqualTo(true).andDeletedEqualTo(false);
        return (int) goodsMapper.countByExample(example);
    }

    public int updateById(LitemallGoods goods) {
        goods.setUpdateTime(LocalDateTime.now());
        return goodsMapper.updateByPrimaryKeySelective(goods);
    }

    public int updateByIdAndShop(LitemallGoods goods) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        goods.setUpdateTime(LocalDateTime.now());
        example.or().andIdEqualTo(goods.getId()).andShopIdEqualTo(goods.getShopId()).andDeletedEqualTo(false);
        return goodsMapper.updateByExampleSelective(goods, example);
    }

    public List<LitemallGoods> queryByKeyword(String keyword) {
        return goodsMapper.selectList(Wrappers.lambdaQuery(LitemallGoods.class)
                .eq(LitemallGoods::getIsOnSale,1)
                .eq(LitemallGoods::getReviewType,2)
                .like(!StringUtils.isEmpty(keyword),LitemallGoods::getName,keyword)
        );
    }

    public void deleteById(Integer id) {
        goodsMapper.logicalDeleteByPrimaryKey(id);
    }

    public void add(LitemallGoods goods) {
        goods.setAddTime(LocalDateTime.now());
        goods.setUpdateTime(LocalDateTime.now());
        goodsMapper.insertSelective(goods);
    }

    public int count() {
        LitemallGoodsExample example = new LitemallGoodsExample();
        example.or().andDeletedEqualTo(false);
        return (int) goodsMapper.countByExample(example);
    }

    public int count(Integer shopId) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        example.or().andDeletedEqualTo(false).andShopIdEqualTo(shopId);
        return (int) goodsMapper.countByExample(example);
    }

    public List<Integer> getCatIds(Integer brandId, String keywords, Boolean isHot, Boolean isNew) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        LitemallGoodsExample.Criteria criteria1 = example.or();
        LitemallGoodsExample.Criteria criteria2 = example.or();

        if (!StringUtils.isEmpty(brandId)) {
            criteria1.andBrandIdEqualTo(brandId);
            criteria2.andBrandIdEqualTo(brandId);
        }
        if (!StringUtils.isEmpty(isNew)) {
            criteria1.andIsNewEqualTo(isNew);
            criteria2.andIsNewEqualTo(isNew);
        }
        if (!StringUtils.isEmpty(isHot)) {
            criteria1.andIsHotEqualTo(isHot);
            criteria2.andIsHotEqualTo(isHot);
        }
        if (!StringUtils.isEmpty(keywords)) {
            criteria1.andKeywordsLike("%" + keywords + "%");
            criteria2.andNameLike("%" + keywords + "%");
        }
        criteria1.andIsOnSaleEqualTo(true);
        criteria2.andIsOnSaleEqualTo(true);
        criteria1.andDeletedEqualTo(false);
        criteria2.andDeletedEqualTo(false);

        List<LitemallGoods> goodsList = goodsMapper.selectByExampleSelective(example, Column.categoryId);
        List<Integer> cats = new ArrayList<Integer>();
        for (LitemallGoods goods : goodsList) {
            cats.add(goods.getCategoryId());
        }
        return cats;
    }

    public boolean checkExistByName(Integer shopId, String name) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        if(shopId != null){
            example.or().andNameEqualTo(name).andShopIdEqualTo(shopId).andIsOnSaleEqualTo(true).andDeletedEqualTo(false);
        }else{
            example.or().andNameEqualTo(name).andIsOnSaleEqualTo(true).andDeletedEqualTo(false);
        }
        return goodsMapper.countByExample(example) != 0;
    }


    public List<LitemallGoods> findByCategoryId(Integer id) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        example.or().andCategoryIdEqualTo(id).andDeletedEqualTo(false);
        return goodsMapper.selectByExampleSelective(example, columns);
    }


    public List<LitemallGoods> findByCategoryId(Integer id, Integer shopId) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        example.or().andCategoryIdEqualTo(id).andShopIdEqualTo(shopId).andDeletedEqualTo(false);
        return goodsMapper.selectByExampleSelective(example, columns);
    }

    public List<LitemallGoods> findByCategoryIdAndShopId(Integer id, Integer shopId) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        LitemallGoodsExample.Criteria criteria = example.createCriteria();
        criteria.andCategoryIdEqualTo(id).andIsOnSaleEqualTo(true).andDeletedEqualTo(false);

        return goodsMapper.selectByExampleSelective(example, columns);
    }


    public List<LitemallGoods> queryPutOnSale(Integer shopId) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        LitemallGoodsExample.Criteria criteria1 = example.or();
        if (!StringUtils.isEmpty(shopId)) {
            criteria1.andShopIdEqualTo(shopId);
        }
        criteria1.andIsOnSaleEqualTo(true);
        criteria1.andDeletedEqualTo(false);

        return goodsMapper.selectByExampleSelective(example);
    }


    public List<LitemallGoods> findByIds(List<Integer> goodsIds) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        example.or().andIdIn(goodsIds).andDeletedEqualTo(false);
        return goodsMapper.selectByExample(example);
    }

    public List<LitemallGoods> queryHead() {
        LitemallGoodsExample example = new LitemallGoodsExample();
        example.or().andShopIdIsNull().andDeletedEqualTo(false);
        return goodsMapper.selectByExample(example);
    }

    public List<LitemallGoods> queryByShopId(Integer shopId) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        LitemallGoodsExample.Criteria criteria1 = example.or();
        LitemallGoodsExample.Criteria criteria2 = example.or();
        if (shopId != null) {
            criteria1.andShopIdEqualTo(shopId);
            criteria1.andDeletedEqualTo(false);
        }
        criteria2.andShopIdIsNull();
        criteria1.andDeletedEqualTo(false);
        return goodsMapper.selectByExampleSelective(example, columnOpss);
    }
    
    public IPage<LitemallGoods> queryByCondition(String goodsSn, String name, Integer shopId
    		, Integer regionId, Integer reviewType, Integer page, Integer size, String sort, String order,Integer categoryl3) {
    	//PageHelper.startPage(page, size);
        return goodsMapperEx.selectByCondition(new Page<>(page,size),shopId, goodsSn, name, regionId, reviewType, sort, order,categoryl3);
    }


    public List<LitemallGoods> queryShopGoodsByCondition(GoodsQueryVo query, Integer page, Integer size, String sort, String order) {
    	//PageHelper.startPage(page, size);
    	return goodsMapperEx.queryShopGoodsByCondition(query, sort, order);
    }
    
    public List<LitemallGoods> queryShopGoods(Integer shopId) {
        LitemallGoodsExample example = new LitemallGoodsExample();
        example.or().andShopIdEqualTo(shopId).andDeletedEqualTo(false);
        return goodsMapper.selectByExampleSelective(example);
    }


    public String[] getByIds(String[] selectGoods) {
        List<LitemallGoods> litemallGoods = goodsMapper.selectBatchIds(Arrays.asList(selectGoods));
        if(litemallGoods!=null&&!litemallGoods.isEmpty()){
            List<String> collect = litemallGoods.stream().map(category -> category.getName()).collect(Collectors.toList());
            return collect.toArray(new String[collect.size()]);
        }
        return new String[0];
    }

    public List<LitemallGoods> selectBatchIds(List<Integer> ids) {
        return goodsMapper.selectBatchIds(ids);
    }


    public  List<LitemallGoods> selectListByIsOnSale(Integer isOnSale) {
        return goodsMapper.selectList(Wrappers.lambdaQuery(LitemallGoods.class).eq(LitemallGoods::getIsOnSale,isOnSale));
    }
}
